package com.example.lotterysystem.service.activitystatus.impl;

import com.example.lotterysystem.common.enums.GlobalErrorCodeEnum;
import com.example.lotterysystem.common.exception.GlobalException;
import com.example.lotterysystem.service.ActivityService;
import com.example.lotterysystem.service.activitystatus.ActivityStatusManager;
import com.example.lotterysystem.service.activitystatus.operator.AbstractActivityOperator;
import com.example.lotterysystem.service.dto.TransferActivityStatusDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@Slf4j
@Component
public class ActivityStatusManagerImpl implements ActivityStatusManager {

    @Autowired
    private ActivityService activityService;

    @Autowired
    private final Map<String, AbstractActivityOperator> map = new HashMap<>();
    // map<String, AbstractActivityOperator>

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void handlerEvent(TransferActivityStatusDTO statusDTO) {
        if(CollectionUtils.isEmpty(map)){
            log.warn("map 为空");
            return;
        }
        Map<String, AbstractActivityOperator> tmpMap = new HashMap<>(map);
        boolean update = processTransferStatus(statusDTO, tmpMap, 1);
        update = processTransferStatus(statusDTO, tmpMap, 2) || update;

        if(update){
            activityService.cacheActivity(statusDTO.getActivityId());
        }
    }

    @Override
    public void rollbackHandleEvent(TransferActivityStatusDTO statusDTO) {
        for (AbstractActivityOperator operator : map.values()){
            operator.transfer(statusDTO);
        }
        activityService.cacheActivity(statusDTO.getActivityId());
    }

    private boolean processTransferStatus(TransferActivityStatusDTO statusDTO,
                       Map<String, AbstractActivityOperator> map, int sequence) {
        Iterator<Map.Entry<String, AbstractActivityOperator>> iterator = map.entrySet().iterator();
        boolean update = false;
        while (iterator.hasNext()){
            AbstractActivityOperator operator = iterator.next().getValue();
            if(operator.sequence() != sequence || !operator.checkTransfer(statusDTO)){
                continue;
            }
            if(!operator.transfer(statusDTO)){
                log.error("{} 转换失败 ", operator.getClass().getName());
                throw new GlobalException(GlobalErrorCodeEnum.ACTIVITY_STATUS_TRANSFER_ERROR);
            }
            iterator.remove();
            update = true;
        }
        return update;
    }
}
